import { Collection, DatasetListItem, MAX_NAME_LENGTH } from '@/common';
import datasetService from '@/api/services/datasetService';
import { useCallback, useEffect, useState } from 'react';
import {
  Button,
  Input,
  message,
  Modal,
  Space,
  Spin,
  Splitter,
  Table,
  Typography,
  TableColumnsType
} from 'antd';
import {
  CloseOutlined,
} from '@ant-design/icons';
import { SvgIcon } from '@/components/icon';
import dayjs from 'dayjs';
import { useUpdateEffect } from 'react-use';
import { useDebounceFn } from 'ahooks';
import useWindowWidth from '@/hooks/event/use-window-width';
import DeleteConfirmModal from '@/pages/datasets/components/DeleteConfirmModal';
import EmptyTip from '@/components/EmptyTip';
import { Size } from '@/types/common';
import { useContextSelector } from 'use-context-selector';
import { ApiManageContext } from '../context';
import { ApiDatasetEvent, ApiItem, BusinessItem } from '@/types/api';
import React from 'react';
import BusinessEditModal from '@/pages/api-manage/components/BusinessEditModal';
import { debounce } from 'lodash';
import { useParams } from '@/router/hooks';
import Modals from '@/components/modals/Modals';
import { validateAndConvertValue } from '@/pages/api-manage/components/NewApiModal';
import Tables from '@/components/tables/tables';
import AuthModal from '@/components/auth-modal/auth-modal';
import useModal from '@/hooks/use-modal/useModal';
import { Search } from '@/components/eai-design';
import { convertHeaderAuthToFormData, formatAuthData, formatAuthConfig } from '@/utils/auth';
import ParamsEditModal from '@/pages/api-manage/components/ParamsEditModal';

const { Text } = Typography;

interface Props {
  selectedItem: DatasetListItem | undefined;
  isAdmin: boolean;
  isPermit: boolean;
  parentSize: Size;
}

interface ExpandedDataType {
  function: object;
  http_method: string;
  http_url: string;
  type: string;
}

interface AuthDefaultData {
  appId?: string;
  datasetId?: string;
  headerAuth?: object;
}

interface BusinessItemData {
  name?: string;
  description?: string;
  parameters?: any[];
  http_url?: string;
  http_method?: string;
  headerAuth?: any;
}

const ApiTable = ({ selectedItem, isAdmin, isPermit, parentSize }: Props) => {
  const modal = useModal('input');
  const [collections, setCollections] = useState<Collection[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  const [searchValue, setSearchValue] = useState('');
  const [loading, setLoading] = useState(true);
  const [renameModalVisible, setRenameModalVisible] = useState(false);
  const [deleteModalVisible, setDeleteModalVisible] = useState(false);
  const [selectedRows, setSelectedRows] = useState<Collection[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [method, setMethod] = useState('get');
  const [path, setPath] = useState('');
  const { appId = '' } = useParams() as { appId: string };
  const [isBatchDelete, setIsBatchDelete] = useState(false);
  const [editItem, setEditItem] = useState<Collection | undefined>(undefined);
  const { isPc } = useWindowWidth();
  const [expandedData, setExpandedData] = useState<{ [key: string]: BusinessItem[] }>({});
  const [expandLoading, setExpandLoading] = useState<{ [key: string]: boolean }>({});
  const { event$ } = useContextSelector(ApiManageContext, (s) => s);

  const [businessEditModalVisible, setBusinessEditModalVisible] = useState(false);
  const [isAddMode, setIsAddMode] = useState(false);
  const [onItem, setOnItem] = useState<BusinessItemData>({});
  const [funcProp, setFuncProp] = useState<ApiItem | null>(null);
  const [recordId, setRecordId] = useState<string>('');
  const [authConfig, setAuthConfig] = useState<any>(null);
  const [headerAuth, setHeaderAuth] = useState<any>({});
  const [authData, setAuthData] = useState<string>('');
  const [updateParamsData, setUpdateParamsData] = useState({});
  const [paramsEditModalVisible, setParamsEditModalVisible] = useState<boolean>(false);

  const expandColumns: TableColumnsType<BusinessItem> = [
    { title: '参数名称', dataIndex: 'name', key: 'name', width: '100%', ellipsis: true },
    {
      title: '参数类型', dataIndex: 'type', key: 'type', width: '100%', ellipsis: true,
      render: (type) => (
        <div className="min-w-14 size-fit rounded-[4px] border border-line-2 bg-bg-4 px-2 text-center">
          <span>{type}</span>
        </div>
      ),
    },
    { title: '参数说明', dataIndex: 'description', key: 'description', width: '100%', ellipsis: true },
    { title: '必须', dataIndex: 'required', key: 'required', width: '100%', ellipsis: true },
  ];

  const fetchExpandedData = async (record: Collection) => {
    setExpandLoading((prev) => ({ ...prev, [record.collectionId]: true }));
    const data = await datasetService.apiDataV2List(record.collectionId);
    const apiItem = data?.metadata?.function as ApiItem;
    const properties = apiItem.function.parameters;
    const expandDataSource = Object.entries(properties).map(([key, value]: [string, any]) => ({
      name: value.name,
      type: value.type,
      description: value.description,
      required: value.required ? '是' : '否',
    }));
    setExpandedData((prev) => ({ ...prev, [record._id]: expandDataSource }));
    setExpandLoading((prev) => ({ ...prev, [record._id]: false }));

    const apiItemnew = transform(apiItem.function);
    if (apiItemnew) {
      apiItemnew.http_url = apiItem.http_url;
      apiItemnew.http_method = apiItem.http_method;
      apiItemnew.headerAuth = data?.metadata?.headerAuth || {};
    }

    setRecordId(data?._id || '');
    setFuncProp(apiItem);
    setOnItem(apiItemnew);
  };

  const submit = useCallback(
    debounce(async (values) => {
      try {
        console.log(values, '----values---submit');

        const newProp = {
          http_url: values.http_url,
          http_method: values.http_method,
          type: 'function',
          function: {
            name: values.name,
            description: values.description,
            parameters: values.parameters,
          },
        }

        if (!editItem?._id || !editItem?.fileName || !editItem?.datasetId) {
          message.error('编辑项信息不完整');
          return;
        }

        await datasetService.updateDatesetData({
          id: editItem.collectionId,
          name: editItem.fileName,
          datasetId: editItem.datasetId,
          functionSchema: newProp,
          headerAuth: values.headerAuth,
        });

        message.success('修改成功');
        setExpandedData((prev) => ({
          ...prev,
          [editItem?._id || '']: values.parameters,
        }));
        run();
        setBusinessEditModalVisible(false);
        setRecordId('');
        if (editItem) {
          fetchExpandedData(editItem);
        }
      } catch (error) {
        console.error('API Error:', error);
      }
    }, 300),
    [funcProp, recordId, editItem],
  );

  const generateKeyValueObject = (
    list: {
      first: string;
      second: string;
      third: string;
      fourth: string;
      enum: string[];
    }[],
  ): Record<string, { type: string; description: string; enum?: any[]; required: boolean }> => {
    return list.reduce((acc, item) => {
      const paramObject: {
        type: string;
        description: string;
        enum?: any[];
        required: boolean;
      } = {
        type: item.third || 'string',
        description: item.second,
        required: item.fourth === '是' ? true : false,
      };

      if (item.enum && item.enum.length > 0) {
        paramObject.enum = [
          ...new Set(
            item.enum.map((value) => {
              const { convertedValue } = validateAndConvertValue(item.third, String(value));
              return convertedValue;
            }),
          ),
        ];
      }

      acc[item.first] = paramObject;
      return acc;
    }, {} as Record<string, { type: string; description: string; enum?: any[]; required: boolean }>);
  };

  const transform = (data: any) => {
    const userinfoEntries = convertObjectToKeyValueArray(
      data.parameters.properties || {},
      data.parameters.required,
    );

    const newData = {
      ...data,
      properties: {
        list: userinfoEntries,
      },
    };
    return newData;
  };

  function convertObjectToKeyValueArray<T>(
    obj: Record<string, T>,
    required: string[],
  ): Array<{
    name: string;
    description: string;
    type: string;
    required: string;
    enum: any[];
  }> {
    return Object.entries(obj || {}).map(([key, value]: [string, any]) => ({
      name: key,
      description: value.description || '',
      type: value.type || '',
      required: required.includes(key) ? '是' : '否',
      enum: value?.enum || [],
    }));
  }

  const rowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: Collection[]) => {
      setSelectedRows(selectedRows);
      setSelectedRowKeys(selectedRowKeys);
    },
    selectedRowKeys: selectedRowKeys,
  };

  const columns = [
    {
      title: '数据接口名称',
      dataIndex: 'fileName',
      key: 'fileName',
      width: '50%',
      render: (fileName: string) => {
        const arr = fileName.split(/:(.*)/, 2);

        return (
          <div className="flex w-full items-center">
            <SvgIcon color="#33ADFF" icon="icon-api" size={24} />
            <Text
              ellipsis={{ tooltip: arr[1] }}
              className="ml-2"
              style={{ maxWidth: isPc ? `${parentSize.width * 0.5}px` : '100px' }}
            >
              {arr[1]}
            </Text>
          </div>
        );
      },
    },
    {
      title: '请求方法',
      dataIndex: 'fileName',
      key: 'method',
      render: (fileName: string) => {
        const arr = fileName.split(/:(.*)/, 2);

        return (
          <div className="min-w-14 max-w-14 rounded-[4px] border border-line-2 bg-bg-4 px-2 text-center">
            <span>{arr[0].toUpperCase()}</span>
          </div>
        );
      },
    },
    {
      title: '时间',
      dataIndex: 'updateTime',
      key: 'updateTime',
      width: '200px',
      render: (updateTime: string) => (
        <span>{dayjs(updateTime).format('YYYY-MM-DD HH:mm:ss')}</span>
      ),
      onCell: () => ({ style: { flex: '1' } }),
    },
    {
      title: '操作',
      key: 'action',
      width: '100px',
      render: (_: any, record: Collection) => (
        <div className="flex items-center">
          {isAdmin ? (
            <div className="flex cursor-pointer items-center gap-2 text-@brand-color">
              <Button
                type="text"
                style={{
                  background: 'none',
                  border: 'none',
                  font: 'inherit',
                }}
                onClick={(e) => {
                  e.stopPropagation();
                  setEditItem(record);
                  fetchExpandedData(record);
                  setIsAddMode(false);
                  setBusinessEditModalVisible(true);
                }}
              >
                <SvgIcon icon="singleedit" />
                修改
              </Button>

              <Button
                type="text"
                danger
                style={{
                  background: 'none',
                  border: 'none',
                  font: 'inherit',
                }}
                onClick={(e) => {
                  e.stopPropagation();
                  setEditItem(record);
                  setDeleteModalVisible(true);
                }}
              >
                <SvgIcon icon="deltongbu" />
                删除
              </Button>
            </div>
          ) : (
            '-'
          )}
        </div>
      ),
    },
  ];

  const handlePageChange = (page: number, pageSize: number) => {
    setPage(page);
    setPageSize(pageSize);
  };

  const paginationConfig = {
    current: page,
    pageSize: pageSize,
    pageSizeOptions: [10, 20, 50, 100],
    total: total,
    onChange: handlePageChange,
    showQuickJumper: true,
    showSizeChanger: true,
  };

  const { run } = useDebounceFn(
    async () => {
      await getCollections();
    },
    {
      wait: 300,
    },
  );

  const clearSelections = () => {
    setSelectedRows([]);
    setSelectedRowKeys([]);
  };

  const getCollections = async () => {
    try {
      if (!selectedItem) {
        return;
      }
      const res = await datasetService.getDatasetFileList({
        datasetId: selectedItem?._id || selectedItem?.id || '',
        page: page,
        page_size: pageSize,
        searchText: searchValue,
        offset: (page - 1) * pageSize,
        app_id: appId,
        type: 'API',
      });
      setCollections(res.list);
      setTotal(res.total);
    } catch (error) {
      console.error(error);
    } finally {
      clearSelections();
      setLoading(false);
    }
  };

  const rename = async () => {
    const newPath = path.trim();
    const fullName = `${method}:${newPath}`;
    if (!newPath) {
      message.error('名称不能为空');
      return;
    }
    if (newPath.length > MAX_NAME_LENGTH) {
      message.error(`名称长度不能超过 ${MAX_NAME_LENGTH} 字符`);
      return;
    }
    if (!editItem) {
      return;
    }
    await datasetService.updateDatasetCollection({
      id: editItem?._id,
      name: fullName,
    });
    message.success('修改名称成功！');
    setRenameModalVisible(false);
    setEditItem(undefined);
    run();
  };

  const handleDeleteConfirm = async () => {
    if (isBatchDelete) {
      const promises = selectedRows.map(async (row) => {
        await datasetService.datasetDeleteApi({
          collectionId_list: [row?.collectionId],
          appId: appId,
          datasetId: selectedRows[0]?.datasetId,
        });
      });

      await Promise.all(promises);
    } else {
      if (!editItem) {
        return;
      }
      await datasetService.datasetDeleteApi({
        collectionId_list: [editItem?.collectionId],
        appId: appId,
        datasetId: editItem?.datasetId,
      });
    }
    message.success('删除成功！');
    setDeleteModalVisible(false);
    setEditItem(undefined);
    setIsBatchDelete(false);
    clearSelections();
    run();
  };

  const handleBatchDelete = async () => {
    setIsBatchDelete(true);
    setDeleteModalVisible(true);
  };

  useEffect(() => {
    setPage(1);
    setPageSize(10);
    setTotal(0);
    if (selectedItem) {
      setLoading(true);
      run();
    } else {
      run();
      setCollections([]);
    }
  }, [selectedItem]);

  useUpdateEffect(() => {
    setLoading(true);
    run();
  }, [page, pageSize]);

  useUpdateEffect(() => {
    setLoading(true);
    setPage(1);
    setPageSize(10);
    run();
  }, [searchValue]);

  event$?.useSubscription((val) => {
    if (val == ApiDatasetEvent.REFRESHCOLLECTION) {
      setLoading(true);
      setPage(1);
      setPageSize(10);
      setTotal(0);
      setSearchValue('');
      run();
    }
  });

  useEffect(() => {
    getBusinessAuth()
  }, []);

  const getBusinessAuth = () => {
    datasetService.getBusinessAuth(appId, selectedItem?._id || selectedItem?.id || '').then((res) => {
      setAuthConfig(res?.headerAuth || {});
      setAuthData(formatAuthData(res?.headerAuth));
    }).catch((error) => {
      console.error('获取工具列表失败:', error);
    })
  };

  const handleSetting = async () => {
    modal.input.open();
  };

  const handleAuthSubmit = (value: object) => {
    const params = {
      headerAuth: formatAuthConfig(value),
      datasetId: selectedItem?._id || selectedItem?.id || '',
    }
    datasetService.updateBusinessAuth(appId, params as AuthDefaultData).then((res) => {
      modal.input.close();
      getBusinessAuth();
      message.success('配置成功');
    }).catch((error) => {
      console.error('获取工具列表失败:', error);
    })
  };

  const handleUpdateParamsValue = ((value: any) => {
    setUpdateParamsData(value);
    setParamsEditModalVisible(true);
  });

  const handleAddParams = ((value: any) => {
    setOnItem(value);
    setParamsEditModalVisible(true);
  });

  const handleParamsClose = (() => {
    setUpdateParamsData({});
    setParamsEditModalVisible(false);
  });

  const handleAddBusinessInterface = () => {
    const defaultData = {
      name: '',
      description: '',
      parameters: [],
      http_url: '',
      http_method: 'GET',
      headerAuth: authConfig || {}
    };
    setOnItem(defaultData);
    setIsAddMode(true);
    setBusinessEditModalVisible(true);
  };

  const handleAddConfirm = async (values: any) => {
    console.log(values, '----values---handleAddConfirm');

    try {
      const newProp = {
        http_url: values.http_url,
        http_method: values.http_method,
        type: 'function',
        function: {
          name: values.name,
          description: values.description,
          parameters: values.parameters,
        },
      }

      await datasetService.createDatesetData({
        datasetId: selectedItem?._id || selectedItem?.id || '',
        appId: appId,
        name: values.name,
        functionSchema: newProp,
        headerAuth: values.headerAuth,
      });

      message.success('新增成功');
      setBusinessEditModalVisible(false);
      setIsAddMode(false);
      setOnItem({});
      run();
    } catch (error) {
      console.error('API Error:', error);
    }
  };

  const handleParamsOk = ((value: any) => {
    if (onItem && onItem.parameters && Array.isArray(onItem.parameters)) {
      const index = value.index;
      if (index !== null && index >= 0) {
        if (index < onItem.parameters.length) {
          const duplicateIndex = onItem.parameters.findIndex((param: any, i: number) =>
            param.name === value.name && i !== index
          );

          if (duplicateIndex !== -1) {
            message.error(`字段名 "${value.name}" 已存在，请使用其他名称`);
            return;
          }

          const updatedParameters = [...onItem.parameters];
          updatedParameters[index] = value;

          setOnItem({
            ...onItem,
            parameters: updatedParameters
          });
          message.success(`参数 "${value.name}" 修改成功`);
        } else {
          message.error('索引超出范围，修改失败');
        }
      } else {
        const existingIndex = onItem.parameters.findIndex((param: any) => param.name === value.name);

        if (existingIndex !== -1) {
          message.error(`字段名 "${value.name}" 已存在，请使用其他名称`);
          return;
        }

        const updatedParameters = [...onItem.parameters, value];

        setOnItem({
          ...onItem,
          parameters: updatedParameters
        });
        message.success(`参数 "${value.name}" 新增成功`);
      }
    }
    setUpdateParamsData({});
    setParamsEditModalVisible(false);
  });

  const handleParamsChange = (parameters: any[]) => {
    setOnItem((prev) => ({
      ...prev,
      parameters: parameters
    }));
  };

  return (
    <div className="relative flex h-full flex-col gap-4 overflow-y-auto">
      <div className="left-0 top-2 z-10  flex justify-between w-full">
        {isPc && (
          <div className="w-[240px] my-auto">
            <Search
              placeholder="请输入内容"
              onChange={(e) => {
                setSearchValue && setSearchValue(e.target.value);
              }}
              value={searchValue}
              suffix={<SvgIcon icon="work-ic6" size={16} />}
            />
          </div>
        )}
        {isAdmin && (
          <Space className="ml-auto">
            <>
              <Button
                type="text"
                style={{ border: '1px solid #1B6DFA' }}
                onClick={() => { handleSetting() }}
              >
                <SvgIcon icon="ic_setting_blue" size={16} />
                接口集鉴权配置
              </Button>
              <Button
                type="text"
                className='ml-2'
                style={{ border: '1px solid #1B6DFA' }}
                onClick={handleAddBusinessInterface}
              >
                <SvgIcon icon="retry" size={16} />
                新建业务办理接口
              </Button>
            </>
          </Space>
        )}
      </div>

      <Tables
        rowClassName="bg-[#fff] custom-scrollbar"
        className="custom-scrollbar"
        loading={loading}
        dataSource={collections}
        columns={columns}
        paginationProps={paginationConfig}
        rowSelection={isAdmin ? rowSelection : {}}
        rowKey={'_id'}
        expandable={{
          expandedRowRender: (record) => (
            <div>
              {expandLoading[record._id] ? (
                <Spin />
              ) : (
                <div className='my-1 ml-20'>
                  <Table
                    columns={expandColumns}
                    dataSource={expandedData[record._id]}
                    pagination={false}
                    rowKey={'name'}
                  />
                </div>
              )}
            </div>
          ),
          rowExpandable: (record) => record.name !== 'Not Expandable',
          onExpand: (expanded, record) => {
            if (expanded && !expandedData[record._id]) {
              fetchExpandedData(record);
            }
          },
          columnWidth: 10,
        }}
        locale={{
          emptyText: (
            <div className="h-full" style={{ textAlign: 'center', color: '#999' }}>
              {!loading && <EmptyTip />}
            </div>
          ),
        }}
      ></Tables>

      {selectedRows.length > 0 && isAdmin && (
        <div
          className="animated-div"
          style={{
            position: 'fixed',
            bottom: '5%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            background: '#474C5F',
            borderRadius: '50px',
          }}
        >
          <Space className="ml-2 mr-2" style={{ height: '45px' }}>
            <Button
              style={{ color: '#fff' }}
              type="text"
              icon={<CloseOutlined />}
              onClick={clearSelections}
            ></Button>
            <span className="whitespace-nowrap text-nowrap text-xs" style={{ color: '#8E93A4' }}>
              已选 {selectedRows.length} 项
            </span>
            <Splitter />

            <Button style={{ color: '#fff' }} type="text" onClick={handleBatchDelete}>
              删除
            </Button>
          </Space>
        </div>
      )}

      <Modals
        title={<div style={{ textAlign: 'center', width: '100%' }}>重命名</div>}
        open={renameModalVisible}
        onCancel={() => {
          setRenameModalVisible(false);
        }}
        okText="确定"
        cancelText="取消"
        width={300}
        centered
        onOk={rename}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: '60px',
          }}
        >
          <Input value={path} onChange={(e) => setPath(e.target.value)} />
        </div>
      </Modals>

      <DeleteConfirmModal
        visible={deleteModalVisible}
        text={`确定要删除吗？`}
        onCancel={() => {
          setDeleteModalVisible(false);
        }}
        onConfirm={handleDeleteConfirm}
      />

      <BusinessEditModal
        visible={businessEditModalVisible}
        onCancel={() => {
          setBusinessEditModalVisible(false);
          setIsAddMode(false);
          setOnItem({});
        }}
        updateParams={handleUpdateParamsValue}
        addParams={handleAddParams}
        onConfirm={isAddMode ? handleAddConfirm : submit}
        onItem={onItem}
        title={isAddMode ? '新增' : '编辑'}
        isEdit={isAddMode ? false : true}
        onParamsChange={handleParamsChange}
      />

      <ParamsEditModal
        modelData={updateParamsData}
        open={paramsEditModalVisible}
        onCancel={handleParamsClose}
        onSubmit={handleParamsOk}
      />

      <AuthModal
        open={modal.input.isOpen}
        onCancel={modal.input.close}
        onSubmitOk={handleAuthSubmit}
        title='鉴权配置'
        defaultValue={convertHeaderAuthToFormData(authConfig)}
        infoMessage={'在该目录下新建数据接口会默认填充相关鉴权配置'}
        zIndex={1001}
      />
    </div>
  );
};

export default ApiTable;
